package com.zijidelu.luframework.starter.scanner.impl;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zijidelu.luframework.utils.spring.beans.generic.SpringBeanTypeUtil;
import com.zijidelu.luframework.utils.spring.proxy.MyBatisPlusMapperProxyUtil;
import com.zijidelu.luframework.utils.collection.stream.StreamUtil;
import com.zijidelu.luframework.infrastructure.persistence.dao.BaseDAO;
import com.zijidelu.luframework.starter.scanner.AbstractAutoScanner;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.description.type.TypeDescription;
import org.springframework.core.ResolvableType;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Spring Mybatis Plus服务扫描器。
 *
 * @author ZIJIDELU
 * @datetime 2025/10/18 15:52
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class MybatisPlusServiceScanner extends AbstractAutoScanner {

    @Override
    public void start() {
        // 已注册IService的实体类
        final Set<? extends Class<?>> registeredMbpBeanPoClasses = StreamUtil.smartStream(getSpringDynamicBeanRegisterUtil().getBeansOfType(IService.class).values())
                .map(iService -> (IService<?>) iService)
                .map(e -> SpringBeanTypeUtil.resolvableTargetClassTypes(e, IService.class))
                .filter(types -> types.length > 0)
                .map(types -> types[0].resolve())
                .collect(Collectors.toSet());

        // 修改成并行处理，提高扫描效率
        StreamUtil.smartStream(getSpringDynamicBeanRegisterUtil().getBeansOfType(BaseDAO.class).values())
                .map(baseDAO -> (BaseDAO<?>) baseDAO)
                .forEach((dao) -> {
                    // 获取泛型接口的泛型信息
                    final ResolvableType[] resolvableTypes = SpringBeanTypeUtil.resolvableTargetClassTypes(dao, BaseDAO.class);
                    // 提取泛型参数中的实体类
                    final Class<?> poClass = Objects.requireNonNull(resolvableTypes[0].resolve());

                    // 如果实体类已注册 Mybatis Plus 服务，则跳过
                    if (registeredMbpBeanPoClasses.contains(poClass)) {
                        return;
                    }

                    // 获取原始的 Mapper 类
                    final Class<? extends BaseDAO<?>> originalMapperClass = MyBatisPlusMapperProxyUtil.getOriginalMapperClass(dao);
                    String packageName = originalMapperClass.getPackageName();

                    // 创建 Mybatis Plus 服务
                    genericRegisterBeans(calcUniDomain(poClass, "MybatisPlusService"),
                            packageName,
                            TypeDescription.Generic.Builder.parameterizedType(ServiceImpl.class,
                                    originalMapperClass,
                                    poClass
                            ).build(),
                            TypeDescription.Generic.Builder.parameterizedType(IService.class,
                                    poClass
                            ).build()
                    );

                });

    }


}
